package com.xianggu.aop;

import com.xianggu.spring.aop.annotation.*;
import com.xianggu.spring.aop.enums.PointcutEnum;
import com.xianggu.spring.aop.joinPoint.CglibJoinPoint;
import com.xianggu.spring.aop.joinPoint.ProceedingJoinPoint;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author chengjy
 * @date 2025/3/10
 */
@Aspect
public class AopAdviceAnnoDemo{

    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {


        Method around = AopAdviceAnnoDemo.class.getDeclaredMethod("around", ProceedingJoinPoint.class);
        Object invoke = around.invoke(new AopAdviceAnnoDemo(), new Object[]{new CglibJoinPoint(around, null, new Object[]{}, null)});
        System.out.println(22);

    }

    /**
     * 返回需要切入的类全限定名
     *
     * @return
     */
    @Pointcut(value = PointcutEnum.ANNOTATION , path = "com.xianggu.aop.AopMethod")
//    @Pointcut(value = PointcutEnum.EXECUTION , path = "com.xianggu.XiangGuController.*ervice")
//    @Pointcut(value = PointcutEnum.WITHIN , path = "com.xianggu.aop.AopClass")
    public String Pointcut() {
        return "com.xianggu.aop.AopTest";
    }

    /**
     * 方法执行前
     *
     * @param joinPoint
     */
    @Before(value = "Pointcut()")
    public void before(ProceedingJoinPoint joinPoint) {
        System.out.println("1." + joinPoint.getMethod().getName() +"方法执行前");
    }

    /**
     * 方法执行后
     *
     * @param joinPoint
     */
    @After(value = "Pointcut()")
    public void after(ProceedingJoinPoint joinPoint) {
        System.out.println("2." + joinPoint.getMethod().getName() +"方法执行后");
    }

    /**
     * 方法执行异常
     *
     * @param method
     * @param throwable
     */
    @AfterThrowing(value = "Pointcut()")
    public void afterThrowing(Method method, Throwable throwable) {
        System.out.println("2." + method.getName() + "方法执行异常");
    }

    /**
     * 方法执行返回
     *
     * @param joinPoint
     */
    @AfterReturning(value = "Pointcut()")
    public void afterReturning(ProceedingJoinPoint joinPoint) {
        System.out.println("3." + joinPoint.getMethod().getName() +"方法执行返回");
    }

    /**
     * 方法执行环绕通知
     *
     */
    @Around(value = "Pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) {
        System.out.println("4." + joinPoint.getMethod().getName() +"方法执行环绕通知");
        long start = System.currentTimeMillis();
        Object proceed = joinPoint.proceed();
        System.out.println( joinPoint.getMethod().getName() + "方法执行"+ (System.currentTimeMillis() - start) +" 毫秒");
        return proceed;
    }
}
